package cn.wj.school.cloud.security;

import cn.wj.school.cloud.security.context.SecurityContext;
import cn.wj.school.cloud.utils.AjaxUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;


/**
 * @author lidapeng
 */
@Slf4j
//@WebFilter(urlPatterns = "/*",filterName = "loginFilter")
public class SecurityFilter implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityFilter.class);

    private final String loginFormUrl = "/login";

    private final Set<String> ignoreUrl = new HashSet<String>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化忽略的url，不拦截登陆url
        ignoreUrl.add(loginFormUrl);
        ignoreUrl.add("/doLogin");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        // 每次进行context设置，通过session，session的属性不失效
        HttpSession session = request.getSession(true);

        if (session != null && request.isRequestedSessionIdValid()) {
           SecurityContext context =
                    (SecurityContext) session.getAttribute(SecurityContextHolder.SECURITY_CONTEXT);
            // 设置ManagementContext
            if (context != null && context.getAuthentication() != null) {
                SecurityContextHolder.setContext(context);
                try {
                    chain.doFilter(request, response);
                }finally {
                    SecurityContextHolder.clearContext();
                }
                return;
            }
        }
        log.debug("ACCESS_LOG[][][]SecurityFilter[]用户认证[]认证拦截[]用户未认证");
        chain.doFilter(request, response);
    }

    private void invidSessionChain(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

        String url = request.getRequestURI();

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("url:" + url);
        }
        // 非ajax请求
        boolean isAjax = AjaxUtil.isAjax(request);
        if (!isAjax) {
            RequestDispatcher dispatcher = request.getRequestDispatcher(loginFormUrl);
            dispatcher.forward(request, response);
            /*
             * String redirectUrl = request.getContextPath()+loginFormUrl; response.sendRedirect(redirectUrl);
             */
        } else {
            // ajax请求，返回json，替代redirect到login page
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("ajax request or post");
            }

            response.setHeader("Content-Type", "application/json;charset=UTF-8");
            response.setContentType("application/json;charset=UTF-8");
            /**
             * 调用dwz的超时返回状态
             * 
             * @author lidapeng
             */
            String jsonObject = JSONObject.toJSONString(AjaxUtil.ajaxTimeout(null));
            PrintWriter out = response.getWriter();
            out.print(jsonObject);
            out.flush();
            out.close();
        }
    }

    /**
     * 登录才能访问的url
     * @param request
     * @param response
     * @return
     */
    protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
        String uri = request.getRequestURI();
        int pathParamIndex = uri.indexOf(';');

        if (pathParamIndex > 0) {
            // strip everything after the first semi-colon
            uri = uri.substring(0, pathParamIndex);
        }
        // 不需要过滤的地方
        for (String ignore : ignoreUrl) {
            if ("".equals(request.getContextPath())) {
                if (uri.endsWith(ignore)) {
                    return false;
                }
            } else if (uri.endsWith(request.getContextPath() + ignore)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public void destroy() {

    }

}
